<template>
	<div class="filter">
		<div class="flx-justify-between header">
			<h4 v-if="title" class="title sle">
				{{ title }}
			</h4>
			<slot name="headButton"></slot>			
		</div>
		<el-input v-model="filterText" placeholder="输入关键字进行过滤" clearable />
		<el-scrollbar :style="{ height: title ? `calc(100% - 95px)` : `calc(100% - 56px)` }">
			<el-tree ref="treeRef" :default-expand-all="defaultExpand"   :node-key="id" :data="multiple ? treeData : treeAllData"
				:show-checkbox="multiple" :check-strictly="false" :current-node-key="!multiple ? selected : ''"
				:highlight-current="!multiple" :expand-on-click-node="false" :check-on-click-node="multiple"
				:props="defaultProps" :filter-node-method="filterNode" :default-checked-keys="multiple ? selected : []"
				@node-click="handleNodeClick" @check="handleCheckChange">
				<template #default="scope">
					<div class="flx-justify-between label_value">
						<span class="el-tree-node__label ">
							<slot :row="scope">
								{{ scope.node.label }}
							</slot>
						</span>
					</div>
				</template>
			</el-tree>
		</el-scrollbar>
	</div>
</template>

<script setup lang="ts" name="TreeFilter">
import { ref, watch, onBeforeMount, nextTick, defineExpose } from "vue";
import { ElTree } from "element-plus";

// 接收父组件参数并设置默认值
interface TreeFilterProps {
  requestApi?: (data?: any) => Promise<any>; // 请求分类数据的 api ==> 非必传
  data?: { [key: string]: any }[]; // 分类数据，如果有分类数据，则不会执行 api 请求 ==> 非必传
  title?: string; // treeFilter 标题 ==> 非必传
  id?: string; // 选择的id ==> 非必传，默认为 “id”
  label?: string; // 显示的label ==> 非必传，默认为 “label”
  propsId?: string; // 显示的label ==> 非必传，默认为 “label”
  children?: string; // 显示的label ==> 非必传，默认为 “label”
  multiple?: boolean; // 是否为多选 ==> 非必传，默认为 false
  defaultValue?: any; // 默认选中的值 ==> 非必传
  isButton?: boolean; // 是否存在新增按钮 ==> 非必传，默认为 false
  isEdit?: boolean; //选项是否存在编辑修改
  defaultExpand?: boolean; //是否展开
}
const props = withDefaults(defineProps<TreeFilterProps>(), {
  id: "id",
  label: "label",
  children: "children",
  multiple: false,
  isButton: false,
  isEdit: false,
  defaultExpand: true
});

const defaultProps = {
  children: props.children,
  id: props.propsId,
  label: props.label,
  disabled: function (data, node) {
    //带子级的节点不能选中
    if (data.children && data.children.length > 0) {
      return true;
    } else {
      return false;
    }
  }
};

const treeRef = ref<InstanceType<typeof ElTree>>();
const treeData = ref<{ [key: string]: any }[]>([]);
const treeAllData = ref<{ [key: string]: any }[]>([]);

const selected = ref();
const setSelected = () => {
  if (props.multiple) selected.value = Array.isArray(props.defaultValue) ? props.defaultValue : [props.defaultValue];
  else selected.value = typeof props.defaultValue === "string" ? props.defaultValue : "";
};

onBeforeMount(async () => {
  setSelected();
  if (props.requestApi) {
    const { data } = await props.requestApi!();
    treeData.value = data;
    //treeAllData.value = [{ id: "", [props.label]: "全部" }, ...data];
    treeAllData.value = data;
  }
});

// 使用 nextTick 防止打包后赋值不生效，开发环境是正常的
watch(
  () => props.defaultValue,
  () => nextTick(() => setSelected()),
  { deep: true, immediate: true }
);
watch(
  () => props.data,
  (newVal, oldVal) => {
    let that = this;
    //console.log(newVal)
    //console.log(oldVal)
    treeData.value = props.data;
    treeAllData.value = props.data;

    if (props.defaultValue != "") {
      selected.value = props.defaultValue;

      // console.log(props.multiple)
      // console.log(props.defaultValue)
      if (newVal !== oldVal) {
        setTimeout(() => {
          treeRef.value.setCurrentKey(props.defaultValue);
          emit("change", treeRef.value?.getCurrentNode());
        }, 0);
      }
    }

    // if (props.data?.length) {
    // 	console.log(props.data)
    // 	treeData.value = props.data;
    // 	//treeAllData.value = [{ id: "", [props.label]: "全部" }, ...props.data];
    // 	treeAllData.value = props.data;
    // }
  },
  { deep: true, immediate: true }
);

const filterText = ref("");
watch(filterText, val => {
  treeRef.value!.filter(val);
});

// 过滤
const filterNode = (value: string, data: { [key: string]: any }, node: any) => {
  if (!value) return true;
  let parentNode = node.parent,
    labels = [node.label],
    level = 1;
  while (level < node.level) {
    labels = [...labels, parentNode.label];
    parentNode = parentNode.parent;
    level++;
  }
  return labels.some(label => label.indexOf(value) !== -1);
};

// emit
const emit = defineEmits<{
  change: [value: any];
}>();

// 单选
const handleNodeClick = (data: { [key: string]: any }, checkedType: any) => {
  if (props.multiple) return;
  // let getData = {
  // 	id:data[props.id],
  // 	index:data.index,
  // }
  // if(data.parent_index){
  // 	getData.parent_index = data.parent_index
  // }
  emit("change", data);
};

// 多选
const handleCheckChange = () => {
  emit("change", treeRef.value?.getCheckedKeys());
};

// 暴露给父组件使用
defineExpose({ treeData, treeAllData, treeRef });
</script>

<style scoped lang="scss">
@import "./index.scss";
</style>